package com.fivestar.finance.app.injector.module;

import android.content.Context;

import com.fivestar.finance.app.BuildConfig;
import com.fivestar.finance.app.constant.GlobalConfig;
import com.fivestar.finance.app.constant.ServerConstant;
import com.fivestar.finance.library.utils.FileUtils;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Module其实是一个简单工厂模式，Module里面的方法基本都是创建类实例的方法
 * ApplicationModule作用为提供在应用的生命周期中存活的对象
 * 实现了一些 提供的实例构造，后面使用Component来将这些连接起来
 */
@Module //1. 实现一个类 用module 标注
public class ApplicationModule {

    private final Context context;

    public ApplicationModule(Context context) {
        this.context = context;
    }

    @Provides//2.实现一些提供的方法，作为这个模块能给外界提供的构造类
    @Singleton
    public Context provideApplicationContext() {
        return context.getApplicationContext();
    }

    @Provides
    @Singleton
    Interceptor provideInterceptor() {
        // 拦截 header统一添加token
        Interceptor headerInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request newRequest = chain.request().newBuilder().addHeader("tokenId",
                        GlobalConfig.getInstance().getTokenId()).build();
                return chain.proceed(newRequest);
            }
        };
        return headerInterceptor;
    }

    @Provides
    @Singleton
    Cache providesCache() {
        File httpCacheFile = FileUtils.getDiskCacheDir(context, "response");
        return new Cache(httpCacheFile, 1024 * 100 * 1024);
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(Interceptor interceptor, Cache cache) {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        if (BuildConfig.DEBUG) {
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        } else {
            logging.setLevel(HttpLoggingInterceptor.Level.NONE);
        }

        OkHttpClient httpClient = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .addInterceptor(logging)
                .addInterceptor(interceptor)
                .cache(cache)
                .build();
        return httpClient;
    }

    @Provides
    @Singleton
    Retrofit provideRetrofit(OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ServerConstant.BASE_URL)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setDateFormat
                        ("yyyy-MM-dd'T'HH:mm:ss").create()))
                .build();
        return retrofit;
    }

}
